//: Playground - noun: a place where people can play

import UIKit

//for...in可以用在所有实现Sequence的类型上

// MARK: 实现一个IteratorProtocol

//先定义一个实现了IteratorProtocol协议的类型
//IteratorProtocol需要指定一个typealias Element
//提供一个返回Element？的方法next()
class ReverseIterator<T>: IteratorProtocol {
    typealias Element = T
    
    var array: [Element]
    var currentIndex = 0
    
    init(array: [Element]) {
        self.array = array
        currentIndex = array.count - 1
    }
    
    func next() -> Element? {
        if currentIndex < 0 {
            return nil
        }
        else {
            let element = array[currentIndex]
            currentIndex -= 1
            return element
        }
    }
}

//定义Sequence
//制定一个typealias Iterator
//返回一个Iterator? 的方法 makeIterator()
struct ReverseSequence<T>: Sequence {
    typealias Iterator = ReverseIterator<T>
    
    var array: [T]
    
    init(array: [T]) {
        self.array = array
    }
    
    func makeIterator() -> ReverseIterator<T> {
        return ReverseIterator(array: self.array)
    }
}
//
//let arr = [0, 1, 2, 3, 4]
//
//for i in ReverseSequence(array: arr) {
//    print("Index \(i) is \(arr[i])")
//}
//
//let reverseIterator = ReverseSequence(array: arr).makeIterator()
//while let item = reverseIterator.next() {
//    print(item)
//}


// MARK: Currying 柯里化
func addOne(num: Int) -> Int {
    return num + 1
}

func addTo(_ adder: Int) -> (Int) -> Int {
    return {
        num in
        return num + adder
    }
}

let addTwo = addTo(2)
let result = addTwo(6)

//比较大小
func greaterThan(_ comparer: Int) ->(Int) ->Bool {
    return { $0 > comparer }
}

let greaterThan10 = greaterThan(10)
greaterThan10(5)
greaterThan10(11)

// MARK: 使用柯里化封装Target-Action
protocol TargetAction {
    func performAction()
}

struct TargetActionWrapper<T: AnyObject>: TargetAction {
    
    weak var target: T?
    let action:(T) -> () -> ()
    
    func performAction() -> () {
        if let t = target {
            action(t)()
        }
    }
}

enum ControlEvent {
    case touchUpInside
    case valueChanged
}

class Control {
    var actions = [ControlEvent: TargetAction]()
    
    func setTarget<T: AnyObject>(target: T, action: @escaping (T) -> () -> (), controlEvent: ControlEvent) {
        actions[controlEvent] = TargetActionWrapper(target: target, action: action)
    }
    
    func removeTargetForControlEvent(controlEvent: ControlEvent) {
        actions[controlEvent] = nil
    }
    
    func performActionForControlEvent(controlEvent: ControlEvent) {
        actions[controlEvent]?.performAction()
    }
}


// MARK: autoclosure
func logIfTrue(_ predicate: () -> Bool) {
    if predicate() {
        print("True")
    }
}
logIfTrue { () -> Bool in
    return 2 > 1
}
logIfTrue({return 2 < 1})
logIfTrue({ 2 > 3 })
logIfTrue{ 2 < 4 }

func logIfTrue(_ predicate: @autoclosure () -> Bool) {
    if predicate() {
        print("haha")
    }
}

logIfTrue( 2 < 3)

// MARK: ?? 操作符
var level: Int?
var startLevel = 1

var currentLevel = level ?? startLevel

//func ??<T>(optional: T?, defaultValue: @autoclosure () -> T?) -> T?
//func ??<T>(optional: T?, defaultValue: @autoclosure () -> T) -> T
//startLevel在使用中被自动封装为了() -> Int

func ??<T>(optional: T?, defaultValue: @autoclosure () -> T) -> T {
    switch optional {
    case .some(let value):
        return value
    case .none:
        return defaultValue()
    }
}
